import pickle
import socket
import threading
import struct
import queue
import grpc
import asyncio
import time
import AhoEdgeRegisterService_pb2 as ae
import AhoEdgeRegisterService_pb2_grpc as aeg
from core_algorithm import InterStatus
from core_algorithm import Status
import regutil

#通过DNS解析以得到注册中心地址: reg.sdju.ahhhh.com.cn
#同时为避免不期望的缓存现象，不使用系统提供DNS解析，采用第三方库。并设置DNS服务器为dns8.hichina.com

register__address = regutil.get_reg_address()
register_port = 50051
register_server = f'{register__address}:{register_port}'
# TODO 如果可以自动识别本地IP就更好了
import util
local_ip = util.get_local_address()
local_port = 2333
class SyncThread(threading.Thread):

    def __init__(self, addr: str, port = int, logger = None) -> None:
        super().__init__(daemon=False)
        self.queue = queue.Queue(2)
        self.address = addr
        self.port = port
        self.logger = logger
        self.sync_channel = grpc.insecure_channel(register_server)
        self.server_id = 1

    def run(self):
        self.logger.log('同步线程已启动')
        stub = aeg.RegisterServiceStub(self.sync_channel)
        while True:
            try:
                respone = stub.registerService(ae.RegisterInfo(serviceName="avoid", service=ae.Service(status=ae.Service.Status.OK, ipAddress=local_ip, port=self.port)))
                break
            except grpc.RpcError as _:
                self.logger.log('暂时无法连接至注册中心，5秒后重试')
                time.sleep(5.0)
        
        self.logger.log(f'已向注册服务器注册本机服务, serverName=avoid, {local_ip}:{self.port}')
        self.server_id = respone.server_id
        self.logger.log(f"注册服务器给予的本机ID: {respone.server_id}")
        while True:
            stub.heartbeat(ae.Ping(server_id=self.server_id))
            time.sleep(6)


    def SendStatus(self, status: InterStatus):
        if self.queue.full():
            return
        self.queue.put_nowait(status)

    def GetStatus(self) -> InterStatus:
        self.sock.send(pickle.dumps('status|' + self.address))
        print('request for status')
        while True:
            data = self.sock.recv(1024)
           
            if data:
                print('get data')
                self.lastStatus = InterStatus.try_from(data)
                self.carStatus = self.lastStatus
                return self.carStatus